/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */

package br.uniceub.fsw.seguranca.dao;

import br.uniceub.fsw.arquitetura.persistencia.dao.BaseDAO;
import br.uniceub.fsw.arquitetura.persistencia.dao.ConstrutorSQL;
import br.uniceub.fsw.seguranca.vo.ModuloVO;
import br.uniceub.fsw.seguranca.vo.UsuarioVO;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Data Access Object - Usuário
 * Camada de acesso ao banco de dados da entidade Usuário.
 * 
 * @author Bruno Schifer Bernardi
 */
public class UsuarioDAO extends BaseDAO<UsuarioVO> {

    @Override
    public void inserir(UsuarioVO entidade) {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        sql.append("INSERT INTO TB_USUARIO(NO_USUARIO, DS_SENHA)");
        sql.append("VALUES (?,?)");

        List<?> parametros = criarParametros(entidade.getNoUsuario(), entidade.getDsSenha());
        
        Integer idGerado = ((Long) executarInsercao(sql.toString(), parametros)).intValue();

        entidade.setIdUsuario(idGerado);
    }
    
    @Override
    public void alterar(UsuarioVO entidade) {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        sql.append("UPDATE TB_USUARIO SET NO_USUARIO = ?, DS_SENHA = ?");
        sql.append("WHERE ID_USUARIO = ?");

        executarAlteracao(sql.toString(), criarParametros(entidade.getNoUsuario(), entidade.getDsSenha(), entidade.getIdUsuario()));
    }
    
    @Override
    public void excluir(UsuarioVO entidade) {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        sql.append("DELETE FROM TB_USUARIO");
        sql.append("WHERE ID_USUARIO = ?");

        executarAlteracao(sql.toString(), criarParametros(entidade.getIdUsuario()));
    }
    
    @Override
    public UsuarioVO consultarPorId(Serializable id) {
        ConstrutorSQL sql = new ConstrutorSQL();
                
        sql.append("SELECT * FROM TB_USUARIO WHERE ID_USUARIO = ?");
        
        return consultarUm(sql.toString(), criarParametros(id));
    }
    
    @Override
    public List<UsuarioVO> consultarPorExemplo(UsuarioVO exemplo) {
        List<UsuarioVO> listaRetorno = null;

        ConstrutorSQL query = new ConstrutorSQL();

        query.append("SELECT * FROM TB_USUARIO T WHERE 1=1");

        mapearQueryParaExemplo(query, exemplo);

        listaRetorno = consultar(query.toString(), recuperarParametros());

        return listaRetorno;
    }
    
    /**
     * Recupera um único usuário a partir do login dele.
     * 
     * @param dsLogin Login do usuário a ser comparado.
     * @return Objeto usuário.
     */
    public UsuarioVO consultarUmPorLogin(String dsLogin) {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        sql.append("SELECT * FROM TB_USUARIO WHERE NO_USUARIO = ?");
        
        return consultarUm(sql.toString(), criarParametros(dsLogin));
    }
    
    /**
     * Recupera um único usuário a partir do login passado que possua
     * o identificador diferente do passado.
     * 
     * @param idUsuario Id do usuário.
     * @param dsLogin Login do usuário.
     * @return Objeto usuário.
     */
    public UsuarioVO consultarUmPorIdDiferentePorLogin(Integer idUsuario, String dsLogin) {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        sql.append("SELECT * FROM TB_USUARIO WHERE ID_USUARIO <> ? AND UPPER(NO_USUARIO) = ?");
        
        return consultarUm(sql.toString(), criarParametros(idUsuario, dsLogin));
    }

    /**
     * Recupera o usuário se o usuário passado tiver acesso ao módulo passado.
     * 
     * @param modulo Módulo que o usuário está tentando acessar.
     * @param idUsuario Id do usuário.
     * @return Objeto usuário.
     */
    public UsuarioVO consultarUmPorModuloPorIdUsuario(String modulo, Integer idUsuario) {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        ModuloDAO moduloDAO = new ModuloDAO();

        ModuloVO moduloVO = moduloDAO.consultarUmPorNome(modulo);

        // Consulta os modulos pelo id do usuário, sendo que o usuário
        // pode ter acesso ao módulo pelo grupo que ele pertence.
        sql.append("SELECT E.*");
        sql.append("FROM TB_ACESSO A,");
        sql.append("TB_GRUPO B,");
        sql.append("TB_PAPEL C,");
        sql.append("TB_MODULO D,");
        sql.append("TB_USUARIO E");
        sql.append("WHERE A.CD_GRUPO = B.ID_GRUPO");
        sql.append("AND B.ID_GRUPO = C.CD_GRUPO");
        sql.append("AND C.CD_USUARIO = ?");
        sql.append("AND C.CD_USUARIO = E.ID_USUARIO");
        sql.append("AND A.CD_MODULO = D.ID_MODULO");
        sql.append("AND D.ID_MODULO = ?");
        
        return consultarUm(sql.toString(), criarParametros(idUsuario, moduloVO.getIdModulo()));
    }
    
    /**
     * Recupera uma lista completa de usuários ordenada pelo nome
     * 
     * @return lista de usuários
     */
    public List<UsuarioVO> consultarUsuariosOrdenadoPorNome() {
        ConstrutorSQL sql = new ConstrutorSQL();
        
        sql.append("SELECT *");
        sql.append("FROM TB_USUARIO A");
        sql.append("ORDER BY NO_USUARIO ASC");
        
        return consultar(sql.toString());
    }

    @Override
    protected UsuarioVO extrairObjetoResultado(ResultSet rs) throws SQLException {

        UsuarioVO usuario = new UsuarioVO();
        usuario.setIdUsuario(rs.getInt("ID_USUARIO"));
        usuario.setNoUsuario(rs.getString("NO_USUARIO"));
        usuario.setDsSenha(rs.getString("DS_SENHA"));
        usuario.setCdTalento(rs.getInt("CD_TALENTO"));

        return usuario;
    }
    
    @Override
    protected void mapearQueryParaExemplo(ConstrutorSQL query, UsuarioVO exemplo) {

        if(exemplo.getNoUsuario() != null && exemplo.getNoUsuario().length() > 0) {
            query.append("AND T.NO_USUARIO LIKE ?");
            adicionarParametro("%" + exemplo.getNoUsuario() + "%");
        }
            
        if(exemplo.getDsSenha() != null && exemplo.getDsSenha().length() > 0) {
            query.append("AND T.DS_SENHA = ?");
            adicionarParametro(exemplo.getDsSenha());
        }
    }
}
